#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <assert.h>
#include <sys/types.h>    
#include <sys/stat.h>    
#include <fcntl.h>

static int evtdev = -1;
static int fbdev = -1;
static int screen_w = 0, screen_h = 0;


uint32_t NDL_GetTicks() {
  struct timeval tv;
  struct timezone tz;
  gettimeofday (&tv, &tz);
  return tv.tv_sec*1000 + tv.tv_usec/1000;
}

int NDL_PollEvent(char *buf, int len) {
  FILE *fp = open("/dev/events",O_RDWR);
  assert(fp);
  int ret;
  ret = read(fp, buf, len);
  if (ret){
//   printf("buf%s\n",buf);
   return 1;
  }
  else return 0;
/*  fseek(fp,0,SEEK_SET);
  assert(fp != NULL);
  memset(buf,0,len);
   int ret = fread(buf ,1,3,fp);
  fscanf(fp,"%s",buf+3); 
  //printf("%d\n",len);
  int ret = fread(buf,1,len,fp);
  if(ret == 0) return 0;
  for(int i = 0; i < len&&ret != 0;i++)
  {
    if(buf[i] == '\n') 
    {
      buf[i] = '\0';
      return ret;
    }
  }
  fclose(fp);*/
}

void NDL_OpenCanvas(int *w, int *h) {
  if (getenv("NWM_APP")) {
    int fbctl = 4;
    fbdev = 5;
    screen_w = *w; screen_h = *h;
    char buf[64];
    int len = sprintf(buf, "%d %d", screen_w, screen_h);
    // let NWM resize the window and create the frame buffer
    write(fbctl, buf, len);
    while (1) {
      // 3 = evtdev
      int nread = read(3, buf, sizeof(buf) - 1);
      if (nread <= 0) continue;
      buf[nread] = '\0';
      if (strcmp(buf, "mmap ok") == 0) break;
    }
    close(fbctl);
  }
  else{
//   FILE *fp = fopen("/proc/dispinfo","r+");
    int fp = open ("/proc/dispinfo",O_RDWR);
    assert(fp);
    char * buf = malloc(sizeof(char)*24);
//   char * hbuf = buf;
//   char * wbuf = malloc(sizeof(char)*1);
//   wbuf = buf;
     read(fp, buf, 24);
//   while(strncmp(wbuf,"WIDTH:",6)){
//      wbuf++;
//   }
//   wbuf += 6;
//   while(strncmp(hbuf,"HEIGHT:",7)){
//      hbuf++;
//   }
//   hbuf += 7;
   screen_w = 400;
   screen_h = 300;
   if(*w == 0)*w = screen_w;
   if(*h == 0)*h = screen_h; 
//printf("can.w:%d,can.h:%d\n",*w,*h);
   assert(*w <= screen_w && *h <= screen_h);

   // free(buf);
  }
}

void NDL_DrawRect(uint32_t *pixels, int x, int y, int w, int h) {
  int fp = open("/dev/fb",O_RDWR);
  assert(fp);
  for(int l = 0; l < h; l++){
    lseek(fp, 4*(x+(y+l)*screen_w) ,SEEK_SET);//set offset
    write(fp, pixels, 4*w);//write pixels 4*w*h = sizeof pixels bytes
    pixels =(uint32_t *)(pixels + w);
  }
//  fseek(fp, 4 * (y * screen_w + x) ,SEEK_SET);//set offset
  //fwrite(pixels, sizeof(char), 4*w*h, fp);//write pixels 4*w*h = sizeof pixels bytes
  
//  write(fp, pixels, 4*w*h);//write pixels 4*w*h = sizeof pixels bytes
}

void NDL_OpenAudio(int freq, int channels, int samples) {
}

void NDL_CloseAudio() {
}

int NDL_PlayAudio(void *buf, int len) {
  return 0;
}

int NDL_QueryAudio() {
  return 0;
}

int NDL_Init(uint32_t flags) {
  if (getenv("NWM_APP")) {
    evtdev = 3;
  }
  return 0;
}

void NDL_Quit() {
}
